package com.taotao.proxy;

import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author wangjin
 * @title: FeignClientProxy
 * @projectName sw-opefeign-parent
 * @description:
 * @date 2021/11/14 21:55
 */
@Component
@Slf4j
public class FeignClientProxy {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 动态代理技术
     */
    public <T> T create(Class<T> tClass) {
        return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class<?>[]{tClass}, new InvocationHandler() {


            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //1调用服务名称,判断接口上是否有SWFeignClient
                SWFeignClient swFeignClient = tClass.getDeclaredAnnotation(SWFeignClient.class);
                if (swFeignClient == null) {
                    throw new Exception("SWFeignClient is null");
                }
                //2接口如何获取
                String serviceName = swFeignClient.value();
                if (Strings.isBlank(serviceName)) {
                    throw new Exception("服务为空");
                }
                //获取接口地址
                GetMapping getMapping = method.getDeclaredAnnotation(GetMapping.class);
                if (getMapping == null) {
                    throw new Exception("方法为空");
                }
                String[] requestName = getMapping.value();
                //反射拼接参数
                String requestUrl = "http://" + serviceName + "" + requestName[0];
                log.info("requestUrl:{}", requestUrl);
                //3底层采用什么技术发送rest http请求
                ResponseEntity<?> result = restTemplate.getForEntity(requestUrl, method.getReturnType());

                return result.getBody();
            }
        });
    }
}
